package com.edianping.algorithm;

import java.util.List;

import org.apache.log4j.Logger;

import com.edianping.bean.ReviewItemBean;
import com.edianping.config.ConstVars;

public class AlgorithmProduct implements IAlgorithm {

	private static Logger log = Logger.getLogger(AlgorithmProduct.class);

	@Override
	public int calculateScore(List<ReviewItemBean> list) {
		return (int) doCalculate(list, ConstVars.SCORE);
	}

	@Override
	public int calculateRate(List<ReviewItemBean> list) {
		return (int) doCalculate(list, ConstVars.RATE);
	}

	@Override
	public int calculateVelocity(List<ReviewItemBean> list) {
		return (int) doCalculate(list, ConstVars.VELOCITY);
	}

	@Override
	public int calculateService(List<ReviewItemBean> list) {
		return (int) doCalculate(list, ConstVars.SERVICE);
	}

	@Override
	public int calculateReality(List<ReviewItemBean> list) {
		return (int) doCalculate(list, ConstVars.REALITY);
	}

	/**
	 * use the given formula to calculate the score
	 * 
	 * @param list
	 * @return
	 */
	private double doCalculate(List<ReviewItemBean> list, int type) {
		double result = 0;

		double sum1 = 0;
		double sum2 = 0;
		// Wi = ( flowerCount-eggCount +UserReputaion )/2
		// result = sum(Wi*Score)/sum(Wi)
		for (ReviewItemBean item : list) {
			double C = item.getFlower_count() - item.getEgg_count();
			// int W = ( C + item.getUserReputation() )/2;

			// involve the time as weight here
			double T = item.getWeight() + 1;
			double base = Math.log(T) / Math.log(2);
			double W = (C + item.getUserReputation()) / base;

			double score = 0;

			switch (type) {
			case ConstVars.SCORE:
				score = item.getScore();
				break;
			case ConstVars.RATE:
				score = item.getRate();
				break;
			case ConstVars.SERVICE:
				score = item.getService();
				break;
			case ConstVars.REALITY:
				score = item.getReality();
				break;
			case ConstVars.VELOCITY:
				score = item.getVelocity();
				break;
			}

			sum1 += W * score;
			sum2 += W;
		}

		if (sum2 != 0) {
			result = sum1 * 10 / sum2;
			log.debug("sum2 is " + sum2 + ", the score is:" + result);
		} else {
			log.debug("sum2 is zero, so the score has to be zero");
		}

		if (result < 0) {
			log.info("result is less than 0");
			result = 0;
		}

		return result;
	}

}
